// 这里是socket页面的一些信息（优化了vue组件的页面整洁）
import { ElMessage } from "element-plus"
import { getCurrentInstance, reactive, ref, shallowRef, type Ref } from "vue";
import UploadImage from "../assets/General/socket/upload.svg"
import RecordingImage from "../assets/General/socket/recording.svg"
import PhoneImage from "../assets/General/socket/phone.svg"
import AnnouncementImgae from "../assets/General/socket/announcement.svg"
import SearchMessageImage from "../assets/General/socket/search-message.svg"
import type { FileChunk, Chat, FileChat, CurrentGroup, CurrentUser, FriendMenuList, FactoryReturn, ChatList } from "../types/types"
import { TargetChatType, FileSuffixType } from "../types/types"
import { userStore } from "../store/userStore";
import { lazyLoadPiniaStore } from "./factory";

let factory: FactoryReturn = reactive({
    user_store: null,
    friend_store: null,
    chat_store: null
})
setTimeout(async () => {
    const result = await lazyLoadPiniaStore();
    Object.assign(factory, result);
}, 20);



export const optionsName = {
    'Smileys & Emotion': '笑脸&表情',
    'Food & Drink': '食物&饮料',
    'Animals & Nature': '动物&自然',
    'Travel & Places': '旅行&地点',
    'People & Body': '人物&身体',
    Objects: '物品',
    Symbols: '符号',
    Flags: '旗帜',
    Activities: '活动'
}



export const groupOptions: FriendMenuList[] = reactive([
    { label: "好友", value: "friends-list", expanded: false },
    { label: "穿上龙袍", value: "put-on-the-dragon-robe", expanded: false },
    { label: "戴上皇冠", value: "wear-a-crown", expanded: false },
    { label: "拿着权杖", value: "take-the-scepter", expanded: false },
    { label: "我便是王", value: "I-am-the-king", expanded: false }
])

// 存储当前好友信息
export let targetChatFriend = reactive<CurrentUser>({
    username: "",
    uu_id: "",
    gex: "",
    area: "",
    typeOfFriendShips: [],
    avatar: "",
    signatureOfTheIndividual: ""
});
// 存储聊天对象（群聊信息）
export let targetChatGroup = reactive<CurrentGroup>({
    group_id: "",
    group_name: "",
    group_leader: "",
    group_type: "",
    create_at: "",
    member_numbers: 100
})

// 存储At的群成员Id
export let AtMemberIds = ref<string[]>([]);

// 单项：unidirectional   多向：Multi-directional  群发：mass 文件：file  文件分片：chunk
export let messageType = ref<string>("");    // 在这里结合自定义的枚举类型设置变量

export let chatInfo: Chat = reactive({
    content: "",
    toChatId: targetChatFriend.uu_id || targetChatGroup.group_id,
    get userNickName() {
        return getCurrentUserInfo('nickName');
    },
    get userNickAvatar() {
        return getCurrentUserInfo('nickAvatar');
    },
    messageType: "",     // 确保更新这个属性的变化，直接修改对象属性，不使用响应式，或者修改为ref
    get atList() {      // 私聊时置 null，群聊时置 []
        return messageType.value === TargetChatType.Private ? null : AtMemberIds.value;
    },
    status: 'pending' as const
})
function getCurrentUserInfo(infoType: string): string {
    if (infoType === 'nickName') {
        return userStore().userInfo.username;
    } else if (infoType === 'nickAvatar') {
        return userStore().userInfo.avatar;
    } else {
        return "unknown";
    }
}

// 处理点击的群聊对话框
export function disposeGroupChat(data: ChatList) {
    // 清空原有的聊天类型再设置新的变量类型
    messageType.value = "";
    targetChatFriend.uu_id = "";
    if (data.type === 'group-chat') {
        targetChatGroup.group_id = data.group_id!;
        targetChatGroup.group_name = data.group_name!;
    }
    // Object.assign(targetChatGroup, data);   // 直接更新群聊信息
    chatInfo.toChatId = targetChatGroup.group_id;
    messageType.value = "Multi-directional";    // 中间变量
    chatInfo.messageType = "Multi-directional";
}

// 动态存储组件
export const currentComponent = shallowRef();
export const dialogVisible = ref<boolean>(false);
// 存储缓存组件
export const componentCache: Record<string, any> = {};
export function handleMenu(url: string) {
    // 组件对象映射关系
    const componentMap = {
        "ASIDE-MENU-MUSIC": () => import("../components/General/Music/index.vue"),
        "ASIDE-MENU-FILE": () => import("../components/General/File/index.vue"),
        "ASIDE-MENU-COLLECTION": () => import("../components/General/Collection/index.vue"),
        "ASIDE-MENU-DECORATION": () => import("../components/General/Decoration/index.vue"),
        "ASIDE-MENU-SETTING": () => import("../components/General/Setting/index.vue"),
        "ASIDE-MENU-BLOG": () => import("../components/General/Blog/index.vue"),
        "ASIDE-MENU-SPACE": () => import("../components/General/Space/index.vue"),
        "ASIDE-MENU-CONTACT": () => import("../components/General/Contact/index.vue")
    }
    // 根据url获取对应的组件
    const componentLoader = componentMap[url as keyof typeof componentMap];
    if (componentLoader) {
        // 检查组件是否已经缓存
        if (componentCache[url]) {
            // 如果存在则直接使用反之加载
            currentComponent.value = componentCache[url];
            dialogVisible.value = true;
        } else {
            // 如果缓存中不存在则加载
            // 动态加载组件
            componentLoader().then((component) => {
                currentComponent.value = component.default;
                dialogVisible.value = true;
            }).catch((error) => {
                console.error(error);
            })
        }
    }
}

// 控制展示好友详细信息和非详细信息
export function switchShowFriendInfoType() {
    dialogVisible.value = dialogVisible.value ? false : true;
}


// 这是存储普通对话消息的变量
export const chatFileInfo: FileChat = reactive({
    toChatId: targetChatFriend.uu_id,
    messageType: "file",
    fileInfo: {
        fileName: "",
        fileSize: new ArrayBuffer(0),   // 初始化为空，后续填充文件内容
        fileType: ""
    }
})
export const chatChunkFileInfo: FileChunk = reactive({
    messageType: "chunkFIle",
    fileName: "",
    fileSuffix: "",
    chunkNumber: 0,
    totalChunks: 0
})
// 重置文件分片消息
export function resetChunkFileInfo() {
    chatChunkFileInfo.messageType = "";
    chatChunkFileInfo.fileName = "";
    chatChunkFileInfo.fileSuffix = "";
    chatChunkFileInfo.chunkNumber = 0;
    chatChunkFileInfo.totalChunks = 0;
}
// 处理好友点击对象              在这里要存储聊天记录                   这里获取好友聊天记录的方式一定要改
export async function handleChatWithObject(object: ChatList) {
    // 清空原有的消息类型再设置新的消息类型
    messageType.value = "";
    targetChatGroup.group_id = "";
    // Object.assign(targetChatFriend, object);
    if (object.type === 'private-chat') {
        targetChatFriend.uu_id = object.friendId!;
        targetChatFriend.username = object.friendName!;
        // 获取当前对话信息
        chatInfo.toChatId = object.friendId!;
    }
    messageType.value = "unidirectional";       // 中间变量
    chatInfo.messageType = "unidirectional";
    // try {
    //     const testData: ChatMessage | ChatMessage[] = await getChatStoreMessage(user_store!.userInfo.uu_id, object.uu_id)
    //     friendStore().storageMessage(object.uu_id, testData, false);
    // } catch (error) {
    //     return;
    // }
}

// 获取图标url（string类型）
export function getIconUrl(path: string): string {
    return new URL(path, import.meta.url).href;
}


// 处理emoji组件点击事件
export const handleEmojiClick = (val: any): void => {
    chatInfo.content ? chatInfo.content += val : chatInfo.content = val;
}

// 检查信息和websocket信息
function examinMessageInfo(websocket: WebSocket, messageType: string): boolean {
    // 检查 WebSocket 是否处于打开状态
    if (!websocket || websocket.readyState !== WebSocket.OPEN) {
        ElMessage.warning("WebSocket连接异常，请检查网络或重新连接");
        return false;
    }

    if (messageType === 'common') {
        // 检查消息内容是否为空
        if (!chatInfo.content || chatInfo.content.trim() === '') {
            ElMessage.warning("消息内容不能为空");
            return false;
        }
    }

    // 检查通过返回true
    return true;
}
// 发送文件消息
export const sendFileMessage = (websocket: WebSocket, fileContent: ArrayBuffer): void => {
    // 检查websocket状态和信息
    if (!examinMessageInfo(websocket, 'file')) {
        ElMessage.warning("通信异常！");
        return;     // 如果检查不通过则退出
    }

    // 将元数据转换为字符串
    const metadata = {
        toChatId: chatFileInfo.toChatId,
        messageType: chatFileInfo.messageType,
        fileInfo: {
            fileName: chatFileInfo.fileInfo.fileName,
            fileType: chatFileInfo.fileInfo.fileType
        }
    }
    const metadataString = JSON.stringify(metadata);
    // 将数据字符串转换为ArrayBuffer
    const metadataArrayBuffer = new TextEncoder().encode(metadataString).buffer;
    // 创建一个完整的ArrayBuffer，包含元数据和二进制数据
    const totalLength = metadataArrayBuffer.byteLength + fileContent.byteLength;
    const combinedArrayBuffer = new ArrayBuffer(totalLength);
    const combinedView = new Uint8Array(combinedArrayBuffer);

    // 将元数据和二进制数据拼接在一起
    combinedView.set(new Uint8Array(metadataArrayBuffer), 0);
    combinedView.set(new Uint8Array(fileContent), metadataArrayBuffer.byteLength);   // 指定偏移量，确保文件内容不会覆盖元数据


    // 发送文件
    try {
        websocket.send(combinedView);
    } catch (error) {
        console.error(error)
    }
}
// 发送添加好友信息
export const sendAddFriend = (websocket: WebSocket | undefined, content: any): void => {
    if (websocket!.readyState === WebSocket.OPEN) {
        try {
            websocket!.send(JSON.stringify(content));
        } catch (error) {
            console.error(error)
        }
    } else {
        ElMessage.error("取消发送!")
    }
}
// 发送聊天信息（支持群聊和私聊）       优化完毕
export const sendCommonMessage = async (websocket: WebSocket, chatType?: TargetChatType | string): Promise<void> => {    /* --------------------------------- 前置校验 --------------------------------- */
    // 1. 统一检查 WebSocket 与消息
    if (!examinMessageInfo(websocket, 'common')) {
        ElMessage.warning("通信异常！");
        chatInfo.content = "";
        return;     // 如果检查不通过则退出
    }
    // 2. 获取当前登录用户信息
    // const user_store = await (await useFactory()).user_store;
    // 3. 根据聊天类型决定目标 ID   避免if else结构，直接使用三元
    const targetId = chatType === TargetChatType.Private ? targetChatFriend.uu_id : targetChatGroup.group_id;
    if (!targetId) {
        ElMessage.error('目标 ID 无效');
        chatInfo.content = "";
        return;
    }
    /* --------------------------------- 构建并发送消息 --------------------------------- */
    // 1、构建消息负载
    const payload = chatInfo;
    /* --------------------------------- 本地存储消息 --------------------------------- */
    // 需要把消息塞进 friendChatMessages；群聊在业务上另行处理（可扩展）
    if (chatType === TargetChatType.Private) {
        try {
            websocket.send(JSON.stringify(payload))
        } catch (error) {
            chatInfo.content = "";
            console.error(error);
        }

    } else {
        // 发送消息
        try {
            websocket.send(JSON.stringify(payload));
        } catch (error) {
            console.error(error);
            chatInfo.content = "";
        }
    }
    /* --------------------------------- 清理输入框 --------------------------------- */
    if (chatInfo && chatInfo.content) {
        chatInfo.content = "";
    }

    /* --------------------------------- 结果提示 --------------------------------- */
    ElMessage.success(
        chatType === TargetChatType.Private ? '私聊消息已发送' : '群聊消息已发送'
    );
}






// 控制弹出窗菜单显示
export const menuVisible = ref<boolean>(false);
// 存储当前菜单
export const propMenuInfo = reactive({
    currentMenu: "",
    currentMenuKey: "",
    randomKey: 0
})

export const showComponent = ref<boolean>(false);




// 聊天框菜单
export const chatFunctionMenus = reactive<any[]>([
    { label: 'upload', icon: UploadImage, key: 'uploadMenu' },
    { label: 'recording', icon: RecordingImage, key: 'recordingMenu' },
    { label: 'phone', icon: PhoneImage, key: 'phoneMenu' },
    { label: "search", icon: SearchMessageImage, key: 'searchMessage' },
    { label: 'announcement', icon: AnnouncementImgae, key: 'announcementMenu' }
    // { label: 'more', icon: MoreImage, key: 'moreMenu' },
    // { label: 'close', icon: CloseImage, key: 'closeMenu' }
])
export function handleChatMenuClick(key: string): string | undefined {
    // 菜单对象映射关系
    const menuActionMap = {
        uploadMenu: 'uploadFile',
        recordingMenu: 'recordingAction',
        phoneMenu: 'phoneAction',
        searchMessage: 'searchAction',
        moreMenu: 'moreMenuClick',
        closeMenu: 'closeMenuAction',
        announcementMenu: 'announcementAction'
    }
    const action = menuActionMap[key as keyof typeof menuActionMap];
    if (action) {
        return action;
    } else {
        ElMessage.error("出现异常");
        return undefined;
    }
}



// 解析文件消息的函数
export function parseFileInfo(fileInfo: string): any {
    const file = JSON.parse(fileInfo);
    // 默认类型
    let fileType = "unknown";   // 默认类型
    // 根据文件名后缀进行分类
    const suffix = file.fileName.split(".").pop()?.toLowerCase();
    // 根据文件名后缀分类
    if (suffix === 'jpg' || suffix === 'jpeg' || suffix === 'png' || suffix === 'gif') {
        fileType = FileSuffixType.Image;
    } else if (suffix === 'pdf') {
        fileType = FileSuffixType.Document;
    } else if (suffix === 'mp4' || suffix === 'avi' || suffix === 'mov') {
        fileType = FileSuffixType.Video;
    } else {
        fileType = FileSuffixType.Other;
    }
    return {
        fileName: file.fileName,
        fileKey: file.fileKey,
        fileUrl: file.fileUrl,
        fileSize: file.fileSize,
        fileType: fileType
    };
}



// 格式化时间的计算属性
export function convertToLocalTime(timeStamp: string): string {
    // 将字符串转换为数字，然后转换为毫秒
    const numbericTimeStamp = parseFloat(timeStamp);
    // 转换为本地时间
    const date = new Date(Math.floor(numbericTimeStamp * 1000));
    return date.toLocaleString();
}


// 控制修改群聊信息的数组
export const changeGroupInfo = ref<{ label: string; editable: boolean; data: string | any; key: string; changeInfo: string | null }[]>([
    { label: "群聊名称", editable: false, data: "", key: "group-nickname", changeInfo: "" },
    { label: "群备注", editable: false, data: "暂无、后续添加", key: "group-remark", changeInfo: "" },
    { label: "群公告", editable: false, data: "暂无、后续添加", key: "group-announcement", changeInfo: "" },
    { label: "我在本群的昵称", editable: false, data: "", key: "my-group-pet-name", changeInfo: "" }
]);
// 切换编辑状态
export function toggleEditable(item: any) {
    item.editable = !item.editable;
}





